// component/ui/z-tree/z-tree.js
import {
  _toArray
} from '../common/utils';
const customFormControls = require('../common/custom-form-controls')
const formPath = '../z-form-popup/z-form-popup'
Component({
  behaviors: [customFormControls],
  relations: {
    [formPath]: {
      type: 'ancestor',
      linked(target) {},
      linkChanged(target) {},
      unlinked(target) {},
    },
  },

  /**
   * 组件的配置
   */
  options: {
    styleIsolation: 'isolated',
    pureDataPattern: /^_/
  },

  /**
   * 组件的传入样式
   */
  externalClasses: ['extra-style'],

  /**
   * 组件的属性列表
   */
  properties: {
    options: {
      type: Array,
      value: []
    },
    value: {
      type: [Array, String, Number],
      value: []
    },
    multiple: {
      type: Boolean,
      value: false,
    },
    tier: {
      type: Number,
      value: 2,
    },
    restrict: {
      type: Boolean,
      value: false,
    },
    colors: {
      type: Array,
      value: ['#f0f0f0', '#f8f8f8', '#fff']
    },
    prop: {
      type: String,
      value: '',
    }
  },

  /**
   * 组件的初始数据
   */
  data: {
    _options: [],
    showOptions: [],
    showValue: [],
    current: [],
  },

  /**
   * 组件的数据监听
   */
  observers: {
    value(val) {
      wx.nextTick(() => {
        this.updateValue(val)
        this.updateOptions()
      })
    },
    options(val) {
      this.data._options = this.treeToFlat(val)
    }
  },

  /**
   * 组件的生命周期
   */
  lifetimes: {
    created() {
      Object.defineProperty(this, 'parent', {
        get: () => this.getRelationNodes(formPath)[0],
      });
    },
    attached() {},
    detached() {},
  },

  /**
   * 组件的方法列表
   */
  methods: {

    treeToFlat(tree, parent) {
      let res = []
      tree.forEach((item) => {
        res.push({
          parent,
          value: item.value,
          label: item.label,
        })
        if (item.children && item.children.length) {
          res.push(...this.treeToFlat(item.children, item.value))
        }
      })
      return res
    },

    resultToPath(data) {
      const {
        _options
      } = this.data
      let res = []
      _options.forEach(item => {
        if (item.value === data) {
          res.push(item.value)
          if (item.parent) {
            res.unshift(...this.resultToPath(item.parent))
          }
        }
      })
      return res
    },

    updateValue(val) {
      const {
        _options
      } = this.data
      let cur = _toArray(val)
      if (cur && cur.length) {
        this.setData({
          current: cur,
          showValue: this.resultToPath(cur[0])
        })
      } else {
        let list = _options.filter(item => {
          return !item.parent
        })
        this.setData({
          current: cur,
          showValue: list[0] ? [list[0].value] : []
        })
      }
      this.updateOptions()
    },

    updateOptions() {
      const {
        _options,
        showValue,
        tier,
        restrict
      } = this.data
      let showOptions = []
      showValue.forEach((item, index) => {
        if (index === 0) {
          showOptions[index] = _options.filter(_item => {
            return _item.value === item
          })
        }
        if (item && !(restrict && index >= tier)) {
          let list = _options.filter(_item => {
            return _item.parent === item
          })
          if (list && list.length) {
            showOptions[index + 1] = list
          }
        }
      })
      this.setData({
        showOptions,
      })
    },

    onClick(e) {
      const {
        tier,
        current,
        multiple,
        showValue,
        prop
      } = this.data
      let {
        column,
        active,
        item,
      } = e.currentTarget.dataset
      if (column === tier) {
        let path = `showValue[${tier}]`
        if (active) {
          this.setData({
            [path]: multiple ?
              (showValue[tier] || []).some((name) => name !== item.value) : [],
            current: multiple ?
              (current || []).some((name) => name !== item.value) : []
          });
        } else {
          this.setData({
            [path]: multiple ?
              (showValue[tier] || []).push(item.value) : [item.value],
            current: multiple ?
              (current || []).push(item.value) : [item.value]
          });
        }
        if (!(this.parent && prop)) {
          this.triggerEvent('change', current);
        }
      } else {
        showValue[column] = item.value
        showValue.splice(column + 1, 10)
        this.setData({
          showValue,
          current: [],
        })
        this.updateOptions()
      }
    },

    onConfirm() {
      const {
        prop,
        current,
        multiple,
        showOptions,
        tier
      } = this.data;
      let label = [];
      (showOptions[tier] || []).forEach(item => {
        if (current.indexOf(item.value) !== -1) {
          label.push(item.label)
        }
      });
      (this.parent || {}).data._form[prop] = multiple ? current : current[0];
      (this.parent || {}).data._label[prop] = label.join(' ');
    },

    onReset() {
      const {
        showValue
      } = this.data;
      showValue.splice(1, 10)
      this.setData({
        showValue,
        current: [],
      })
      this.updateOptions()
    },

  }
})